package com.tg.login.view;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.text.InputFilter;
import android.text.InputType;
import android.text.Spanned;
import android.text.TextWatcher;
import android.text.method.DigitsKeyListener;
import android.text.method.HideReturnsTransformationMethod;
import android.text.method.PasswordTransformationMethod;
import android.text.method.TransformationMethod;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;

import com.magicindicator.buildins.UIUtil;
import com.tange.base.toolkit.DimenUtil;
import com.tg.appcommon.android.FontUtil;
import com.tange.base.toolkit.StringUtils;
import com.tg.appcommon.android.TGResources;
import com.tg.login.R;

public class TGEditText extends LinearLayout {
    private static final String INPUT_PWD = "textPassword";
    private static final String INPUT_NUMBER = "number";
    private static final String INPUT_NUMBER_PWD = "numberPassword";
    private String mInputType = "textEmailAddress";
    private static final int MAX_LEN = 20;
    private Drawable leftIconDrawable;
    private boolean leftIconDrawableVisible = false;
    private boolean mVisibilityDrawableStart = false;
    private boolean mVisibilityValidateCode = false;
    private boolean mVisibilityImageIcon = false;
    private int mVisibilityCheckBox = 8;
    private EditText mEditText;
    private TextView mTvSendCode;
    private CheckBox mCheckBox;
    private ImageView mImageView;
    private ImageView leftIConIv;
    private float mSplitLineHeight = 0.0f;
    private int mSplitLineColor = Color.TRANSPARENT;
    private int mHintTextColor = Color.TRANSPARENT;
    private float mSplitLineMarginStart = 0.0f;
    private float mSplitLineMarginEnd = 0.0f;
    private int mEtRLResourceId = -1;
    private int mHintTextSize = 14;
    private String mHint;
    private String mDigits;
    private String symbols ="'-!\"#$%&()*,./:;?@[\\]^_`{|}~+<=>";
    public TGEditText(Context context) {
        super(context);
        initContentView(context);
    }

    public TGEditText(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TGEditText(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initParam(context, attrs);
        initContentView(context);
    }


    private void initParam(Context context, @Nullable AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TGEditText);
        mInputType = typedArray.getString(R.styleable.TGEditText_edit_inputType);
        leftIconDrawable = typedArray.getDrawable(R.styleable.TGEditText_edit_left_icon);
        leftIconDrawableVisible = typedArray.getBoolean(R.styleable.TGEditText_edit_left_icon_visible, false);
        mVisibilityDrawableStart = typedArray.getBoolean(R.styleable.TGEditText_edit_visibility_drawableStart, false);
        mVisibilityValidateCode = typedArray.getBoolean(R.styleable.TGEditText_edit_visibility_validateCode, false);
        mVisibilityCheckBox = typedArray.getInt(R.styleable.TGEditText_edit_visibility_checkBox, 8);
        mSplitLineHeight = typedArray.getDimension(R.styleable.TGEditText_edit_splitLine_height, DimenUtil.dp2px(context,0));
        mSplitLineMarginStart = typedArray.getDimension(R.styleable.TGEditText_edit_splitLine_marginStart, DimenUtil.dp2px(context,0));
        mSplitLineMarginEnd = typedArray.getDimension(R.styleable.TGEditText_edit_splitLine_marginEnd, DimenUtil.dp2px(context,0));
        mSplitLineColor = typedArray.getColor(R.styleable.TGEditText_edit_splitLine_color, Color.TRANSPARENT);
        mHintTextColor = typedArray.getColor(R.styleable.TGEditText_edit_hint_textColor, context.getResources().getColor(com.module.commonui.R.color.tg_edit_hint_password));
        mEtRLResourceId = typedArray.getResourceId(R.styleable.TGEditText_edit_background, -1);
        mHintTextSize = typedArray.getInt(R.styleable.TGEditText_edit_hint_textSize, mHintTextSize);
        mHint = typedArray.getString(R.styleable.TGEditText_edit_hint);
        mDigits = typedArray.getString(R.styleable.TGEditText_edit_digits);
        mVisibilityImageIcon = typedArray.getBoolean(R.styleable.TGEditText_edit_visibility_imageIcon, false);
        typedArray.recycle();
    }

    public void setFilters(InputFilter[] filters) {
        mEditText.setFilters(filters);
    }

    public void setTypeface(@Nullable Typeface tf) {
        mEditText.setTypeface(tf);
    }

    public void setCodeTextTypeface(@Nullable Typeface tf){
        mTvSendCode.setTypeface(tf);
    }

    public TextView getCodeText(){
        return mTvSendCode;
    }

    public void addTextChangedListener(TextWatcher watcher) {
        mEditText.addTextChangedListener(watcher);
    }

    public void setOnFocusChangeListener(View.OnFocusChangeListener l) {
        mEditText.setOnFocusChangeListener(l);
    }

    public void setOnClickListener(View.OnClickListener l){
        mEditText.setOnClickListener(l);
    }
    private int getInputType(){
        if (StringUtils.equalsIgnoreCase(mInputType, INPUT_PWD)){
            return InputType.TYPE_TEXT_VARIATION_PASSWORD;
        }
        if (StringUtils.equalsIgnoreCase(mInputType, INPUT_NUMBER)){
            return InputType.TYPE_CLASS_NUMBER;
        }

        if (StringUtils.equalsIgnoreCase(mInputType, INPUT_NUMBER_PWD)){
            return InputType.TYPE_NUMBER_VARIATION_PASSWORD;
        }
        return InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
    }

    private void initContentView(Context context) {
        View view = LayoutInflater.from(context).inflate(R.layout.edit_text, this, true);
        setCheckBox(view);

        setSendCodeView(view);
        setBackgroundResource(view);

        boolean isPwd = StringUtils.equalsIgnoreCase(mInputType, INPUT_PWD);
        if (isPwd){
            mTvSendCode.setVisibility(GONE);
        }
        leftIConIv = findViewById(R.id.left_icon_iv);
        mImageView = findViewById(R.id.iv_image_icon);
        mImageView.setVisibility(mVisibilityImageIcon? VISIBLE : GONE);
        setEditText(view, context, isPwd);

        if (mImageView.getVisibility() == VISIBLE) {
            mImageView.post(new Runnable() {
                @Override
                public void run() {
                    if (mEditText != null) {
                        mEditText.setPadding(0, 0, mImageView.getMeasuredWidth(), 0);
                    }
                }
            });
        }

        setSplitLineView(view);

        int layoutStyle = context.getResources().getInteger(R.integer.layout_tange_global_login_page_style);
        int style = context.getResources().getInteger(R.integer.layout_tange_global_login_page_edit_text_style);

        if (TGResources.isRedirectEnabled() && TGResources.readUiCustomizeSwitch(context)) {
            String s = TGResources.readRedirectConfig(context, "LoginActivity");
            if ("standard".equals(s)) {
                layoutStyle = 0;
            } else if ("background".equals(s)) {
                layoutStyle = 1;
            }

            style = TGResources.readLoginEditTextStyle(context);
        }

        if (layoutStyle == 0) { // 布局样式1

            if (leftIconDrawableVisible && leftIconDrawable != null && style == 1) {
                leftIConIv.setVisibility(View.VISIBLE);
                leftIConIv.setImageDrawable(leftIconDrawable);
            } else {
                leftIConIv.setVisibility(View.GONE);
                final EditText et = view.findViewById(R.id.tg_edit);
                RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) et.getLayoutParams();
                lp.leftMargin = DimenUtil.dp2px(context, 22);
                et.setLayoutParams(lp);
            }
        } else if (layoutStyle == 1) { // 布局样式2
            if (leftIconDrawableVisible && leftIconDrawable != null) {
                leftIConIv.setVisibility(View.VISIBLE);
                leftIConIv.setImageDrawable(leftIconDrawable);
            } else {
                final EditText et = view.findViewById(R.id.tg_edit);
                RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) et.getLayoutParams();
                lp.leftMargin = DimenUtil.dp2px(context, 10);
                et.setLayoutParams(lp);
            }

            final RelativeLayout relativeLayout = view.findViewById(R.id.rl_edit);
            final View spline = view.findViewById(R.id.et_split_line);
            spline.setVisibility(View.GONE);
            if (style == 0) {
                relativeLayout.setBackgroundResource(R.drawable.light_gray2_line_bg);

            } else {
                relativeLayout.setBackgroundResource(R.drawable.light_gray2_rounded_bg);
            }
        }

    }

    public void setImageVisibility(int visibility){
        mImageView.setVisibility(visibility);

        if (visibility == VISIBLE) {
            // 动态设置输入框的右侧间距，避免遮挡此按钮。。。
            mImageView.post(new Runnable() {
                @Override
                public void run() {
                    if (mEditText != null) {
                        if (mCheckBox != null && mCheckBox.getVisibility() == VISIBLE) {
                            mEditText.setPadding(0, 0, mCheckBox.getMeasuredWidth() + mImageView.getMeasuredWidth(), 0);
                        } else {
                            mEditText.setPadding(0, 0, mImageView.getMeasuredWidth(), 0);
                        }
                    }
                }
            });

        }
    }

    public void setImageResource(@DrawableRes int resId){
        mImageView.setImageResource(resId);
    }

    public final void setHint(@StringRes int resId) {
        FontUtil.SetEditTextHintFontSize(mEditText, mHintTextSize, resId);
    }

    public void setInputType(int type) {
        mEditText.setInputType(type);
    }

    private void setEditText(@NonNull View view, Context context, boolean isPwd) {
        mEditText = view.findViewById(R.id.tg_edit);
        mEditText.setInputType(getInputType());
        mEditText.setHintTextColor(mHintTextColor);
        if (!StringUtils.isEmpty(mHint)){
            FontUtil.SetEditTextHintFontSize(mEditText, mHintTextSize, mHint);
        }

        if (!StringUtils.isEmpty(mDigits)){
            mEditText.setKeyListener(DigitsKeyListener.getInstance(mDigits));
        }
        checkBoxClick(mCheckBox);
    }
    public  void setLetterOrDigitFilterSymbolsLength(int len){
        mEditText.setFilters(new InputFilter[]{
                new InputFilter() {
                    public  boolean isLetterLower(final char ch) {
                        return ch >= 'a' && ch <= 'z';
                    }
                    public  boolean isLetterUpper(final char ch) {
                        return ch >= 'A' && ch <= 'Z';
                    }
                    public  boolean isLetter(char ch) {
                        return isLetterUpper(ch) || isLetterLower(ch);
                    }
                    @Override
                    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
                        for (int i=start;i<end;i++){
                            char at = source.charAt(i);
                            if (Character.isWhitespace(at)){
                                return "";
                            }
                            if (!symbols.contains(String.valueOf(at))){
                                if (!Character.isLetterOrDigit(at)){
                                    return "";
                                }
                                if (Character.isLetter(at)&&!isLetter(at)){
                                    return "";
                                }
                            }

                        }
                        return null;
                    }
                },new InputFilter.LengthFilter(len)
        });
    }

    public  void setLetterOrDigitFilterSymbolsLength(){
        setLetterOrDigitFilterSymbolsLength(MAX_LEN);
    }

    private void setSendCodeView(@NonNull View view) {
        mTvSendCode = view.findViewById(R.id.tv_get_code);
        if (mVisibilityValidateCode){
            mTvSendCode.setVisibility(VISIBLE);
        }
        refreshSendCodeViewLocation();
    }

    /**
     * 这个方法用于限制 "发送验证码" 的TextView宽度，并显示输入框与之不重叠
     */
    public void refreshSendCodeViewLocation() {
        if (mVisibilityValidateCode) {

            // 先设置为 Wrap_Content，才能根据新的文本内容算宽度
            RelativeLayout.LayoutParams lp1 = (RelativeLayout.LayoutParams) mTvSendCode.getLayoutParams();
            lp1.width = ViewGroup.LayoutParams.WRAP_CONTENT;
            mTvSendCode.setLayoutParams(lp1);

            // 获取其宽度，发现超过屏幕一半的时候，限制为屏幕一半宽
            mTvSendCode.post(new Runnable() {
                @Override
                public void run() {

                    try {
                        int tvWidth = mTvSendCode.getMeasuredWidth();
                        int[] location = new int[2];
                        mTvSendCode.getLocationInWindow(location);
                        int rightLocation = tvWidth + location[0];

                        int targetLeftLocation = UIUtil.getScreenWidth(getContext()) / 2;

                        final int width = rightLocation - targetLeftLocation;

                        final int finalWidth = tvWidth > width ? width : tvWidth;

                        RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) mTvSendCode.getLayoutParams();
                        lp.width = finalWidth;
                        mTvSendCode.setLayoutParams(lp);

                        if (mEditText != null) {
                            mEditText.setPadding(0, 0, finalWidth + UIUtil.dip2px(getContext(), 20), 0);
                        }
                    } catch (Throwable ex) {}


                }
            });
        }
    }

    private void setBackgroundResource(@NonNull View view) {
        if (mEtRLResourceId != -1){
            RelativeLayout relativeLayout = view.findViewById(R.id.rl_edit);
            relativeLayout.setBackgroundResource(mEtRLResourceId);
        }
    }


    private void setSplitLineView(@NonNull View view) {
        View view1 = view.findViewById(R.id.et_split_line);
        LayoutParams layoutParams = (LayoutParams)view1.getLayoutParams();
        boolean reLayout = false;
        if (mSplitLineHeight > 0.0f){
            layoutParams.height = (int) mSplitLineHeight;
            reLayout = true;
        }

        if (mSplitLineMarginStart > 0.0f){
            layoutParams.leftMargin = (int)mSplitLineMarginStart;
            reLayout = true;
        }

        if (mSplitLineMarginEnd > 0.0f){
            layoutParams.rightMargin = (int)mSplitLineMarginEnd;
            reLayout = true;
        }

        if (reLayout){
            view1.setLayoutParams(layoutParams);
        }
        if (mSplitLineColor != Color.TRANSPARENT){
            view1.setBackgroundColor(mSplitLineColor);
        }
    }

    @SuppressLint("WrongConstant")
    private void setCheckBox(@NonNull View view) {
        mCheckBox = view.findViewById(R.id.checkBox);
        mCheckBox.setOnClickListener(v -> checkBoxClick(mCheckBox));
        if (!StringUtils.equalsIgnoreCase(mInputType, INPUT_PWD)){
            mCheckBox.setVisibility(GONE);
        }else {
            mCheckBox.setVisibility(mVisibilityCheckBox);

            if (mVisibilityCheckBox == VISIBLE) {
                // 动态设置输入框的右侧间距，避免遮挡此按钮。。。
                mCheckBox.post(new Runnable() {
                    @Override
                    public void run() {
                        if (mEditText != null) {
                            if (mImageView != null && mImageView.getVisibility() == VISIBLE) {
                                mEditText.setPadding(0, 0, mCheckBox.getMeasuredWidth() + mImageView.getMeasuredWidth(), 0);
                            } else {
                                mEditText.setPadding(0, 0, mCheckBox.getMeasuredWidth(), 0);
                            }
                        }
                    }
                });

            }
        }
    }


    public void showCheckBox(boolean show) {

        mVisibilityCheckBox = show? View.VISIBLE :  View.GONE;
        mCheckBox.setVisibility(mVisibilityCheckBox);

        if (mVisibilityCheckBox == VISIBLE) {
            // 动态设置输入框的右侧间距，避免遮挡此按钮。。。
            mCheckBox.post(new Runnable() {
                @Override
                public void run() {
                    if (mEditText != null) {
                        if (mImageView != null && mImageView.getVisibility() == VISIBLE) {
                            mEditText.setPadding(0, 0, mCheckBox.getMeasuredWidth() + mImageView.getMeasuredWidth(), 0);
                        } else {
                            mEditText.setPadding(0, 0, mCheckBox.getMeasuredWidth(), 0);
                        }
                    }
                }
            });

        }
    }


    public void setCheckBoxClickListener(@Nullable OnClickListener l) {
        mCheckBox.setOnClickListener(l);
    }

    public CheckBox getCheckBox(){
        return mCheckBox;
    }

    private void checkBoxClick(@NonNull CheckBox checkBox) {
        if (!StringUtils.equalsIgnoreCase(mInputType, INPUT_PWD)){
            return;
        }
        if (checkBox.isChecked()) {
            mEditText.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
        } else {
            mEditText.setTransformationMethod(PasswordTransformationMethod.getInstance());
        }
        if (mEditText.getText().toString().trim().length() > 0) {
            mEditText.setSelection(mEditText.getText().toString().trim().length());
        }
    }

    public String getText(){
        return mEditText.getText().toString();
    }

    public void setText(String text){
        mEditText.setText(text);
    }

    public EditText getEditText() {
        return mEditText;
    }

    public void setTransformationMethod(TransformationMethod method){
        mEditText.setTransformationMethod(method);
    }

    public void setSendCodeClickListener(@Nullable OnClickListener listener){
        mTvSendCode.setOnClickListener(listener);
    }

    public void setSelection(int index) {
        mEditText.setSelection(index);
    }
}
